package com.zhipin.exams;

import com.sun.tools.javac.util.Assert;

import java.util.HashMap;
import java.util.Map;


/**
 * @author admin
 */
public class AttendanceTest {

    public static void main(String[] args) {
        // 12人
        int m = 12;
        // 排7天班
        int t = 7;
        // 需求s
        int[][] s = {
                {3, 2, 3, 4},
                {1, 2, 3, 6},
                {4, 2, 4, 2},
                {3, 3, 3, 3},
                {1, 4, 4, 3},
                {4, 1, 1, 6},
                {0, 5, 1, 6}
        };
        // 排班结果
        String[][] result = new String[][]{
                {"早班", "休息", "晚班", "早班", "中班", "休息", "中班", "晚班", "早班", "休息", "晚班", "休息"},
                {"休息", "晚班", "休息", "中班", "休息", "中班", "晚班", "休息", "休息", "晚班", "休息", "早班"},
                {"早班", "早班", "中班", "晚班", "休息", "晚班", "中班", "早班", "晚班", "休息", "晚班", "早班"},
                {"早班", "中班", "休息", "早班", "晚班", "休息", "中班", "晚班", "休息", "早班", "中班", "晚班"},
                {"中班", "休息", "晚班", "晚班", "中班", "中班", "晚班", "休息", "早班", "中班", "晚班", "休息"},
                {"休息", "早班", "休息", "早班", "休息", "晚班", "休息", "早班", "休息", "早班", "休息", "中班"},
                {"休息", "中班", "中班", "休息", "中班", "休息", "中班", "休息", "晚班", "休息", "中班", "休息"}
        };
        double checkResult = checkResult(m, t, s, result);
        System.out.println("偏差值：" + checkResult + "（越高分越差）");
    }


    /**
     * @param m      员工数量 (0 ~ m-1)
     * @param t      排班天数
     * @param s      排班需求
     * @param result 排班结果
     * @return 结果偏差值
     */
    public static double checkResult(int m, int t, int[][] s, String[][] result) {
        Assert.checkNonNull(result, "结果不能为空");
        Assert.check(t == s.length && s.length == result.length, "结果天数错误");
        Assert.check(result[0].length == m, "结果人数错误");

        Map<String, Integer> shiftMap = new HashMap<>();
        shiftMap.put("早班", 0);
        shiftMap.put("中班", 1);
        shiftMap.put("晚班", 2);
        shiftMap.put("休息", 3);

        int[][] summary = new int[m][4];

        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[i].length; j++) {
                String shift = result[i][j];
                s[i][shiftMap.get(shift)]--;
                summary[j][shiftMap.get(shift)]++;
            }
        }

        for (int[] ints : s) {
            for (int anInt : ints) {
                Assert.check(anInt == 0, "结果与需求不符");
            }
        }

        // 检查冲突
        for (int j = 0; j < m; j++) {
            String shift = result[0][j];
            int ct = 1;
            for (int i = 1; i < result.length; i++) {
                if (result[i][j].equals(shift)) {
                    if ("晚班".equalsIgnoreCase(shift)) {
                        throw new IllegalArgumentException("晚班不能重复");
                    } else if (ct == 1) {
                        ct++;
                    } else {
                        throw new IllegalArgumentException("相同班次不能连续超过2天");
                    }
                } else {
                    shift = result[i][j];
                    ct = 1;
                }
            }
        }

        //计算方差
        double value = 0;
        for (int j = 0; j < 4; j++) {
            double avg = 0;
            for (int[] ints : summary) {
                avg += ints[j];
            }
            avg /= summary.length;

            for (int[] ints : summary) {
                value += Math.pow(ints[j] - avg, 2);
            }
        }
        return value;
    }
}
